package org.feng.customlog.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.feng.customlog.annotation.CustomLog;
import org.feng.customlog.entity.CustomLogProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 自定义日志切面
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2023年06月05日 16时30分
 */
@Aspect
@Component
public class CustomLogAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(CustomLogAspect.class);
    @Resource
    private CustomLogProperties customLogProperties;

    @Pointcut("@annotation(org.feng.customlog.annotation.CustomLog)")
    private void customLog() {
    }

    @Around(value = "customLog()")
    public Object around(ProceedingJoinPoint joinPoint) {
        // 获取方法请求参数
        Object[] args = joinPoint.getArgs();
        // 没开启日志
        if (!customLogProperties.getEnableCustomLog()) {
            LOGGER.info("没开启日志哈");
            try {
                return joinPoint.proceed(args);
            } catch (Throwable e) {
                // TODO 记录日志、处理异常
                throw new RuntimeException(e);
            }
        }

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        CustomLog customLog = method.getAnnotation(CustomLog.class);
        String desc = customLog.desc();
        // 如果注解没有参数，获取方法名称
        String descLog = "".equals(desc) ? joinPoint.getSignature().getName() : desc;
        LOGGER.info("{} 的请求参数是：{}", descLog, Arrays.toString(args));

        Object proceed;
        try {
            proceed = joinPoint.proceed(args);
            if (customLog.enableResultLog()) {
                LOGGER.info("{} 执行的结果是：{}", descLog, proceed);
            }
        } catch (Throwable e) {
            // TODO 记录日志、处理异常
            throw new RuntimeException(e);
        }
        return proceed;
    }
}
